package cn.taketoday.live.client;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ThreadPoolExecutor;

import cn.taketoday.live.config.GlobalData;
import cn.taketoday.live.data.BarrageHeader;
import cn.taketoday.live.data.JsonSequence;
import cn.taketoday.live.data.room.Room;
import cn.taketoday.live.handler.BarrageHandler;
import cn.taketoday.live.handler.MessageHandler;
import cn.taketoday.live.thread.core.ReConnThread;
import cn.taketoday.live.utils.ByteUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * 连接到 B 站弹幕 websocket 服务
 *
 * @author TODAY
 */
@Slf4j
public class Websocket extends WebSocketClient {
  final ThreadPoolExecutor threadPoolExecutor = BarrageHandler.getExecutor();

  public Websocket(String url, Room room) throws URISyntaxException {
    super(new URI(url));
    log.debug("已尝试连接至服务器地址:" + url + ";真实房间号为:" + room.getRoomid() + ";主播名字为:" + room.getUname());
  }

  @Override
  public void onOpen(ServerHandshake handshakedata) {
    log.debug("websocket connect open(连接窗口打开)");
  }

  @Override
  public void onMessage(ByteBuffer message) {
    if (MessageHandler.getInstance().isEnable()) {
      threadPoolExecutor.execute(() -> {
        try {
          MessageHandler.handle(message);
        }
        catch (Exception e) {
          log.debug("解析错误日志生成，请将log底下文件发给管理员,或github开issue发送错误", e);
        }
      });
    }
  }

  @Override
  public void onClose(int code, String reason, boolean remote) {
    log.debug("websocket connect close(连接已经断开)，纠错码: {} reason: {}", code, reason);
    GlobalData.heartByteThread.HFLAG = true;
    if (code != 1000) {
      log.debug("websocket connect close(连接意外断开，正在尝试重连)，错误码:" + code);
      if (!GlobalData.webSocketProxy.isOpen()) {
        if (GlobalData.reConnThread != null) {
          if (GlobalData.reConnThread.getState().toString().equals("TERMINATED")) {
            GlobalData.reConnThread = new ReConnThread();
            GlobalData.reConnThread.start();
          }
          else {

          }
        }
        else {
          GlobalData.reConnThread = new ReConnThread();
          GlobalData.reConnThread.start();
        }
      }
      else {
        GlobalData.reConnThread.RFLAG = true;
      }
    }
  }

  @Override
  public void onError(Exception ex) {
    log.error("[错误信息，请将log文件下的日志发送给管理员]websocket connect error,message:" + ex.getMessage());
  }

  @Override
  public void onMessage(String message) {
    System.out.println("String message->" + message);
  }

  public void send(JsonSequence data) {
    final String json = data.toJSON();
    final byte[] dataBytes = json.getBytes(StandardCharsets.UTF_8);
    final byte[] headerBytes = MessageHandler.toBytes(new BarrageHeader(dataBytes.length));
    send(headerBytes, dataBytes);
  }

  public void send(byte[] headerBytes, byte[] dataBytes) {
    super.send(ByteUtils.mergeBytes(headerBytes, dataBytes));
  }

}
